home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
- #include "WINGsP.h"
-
-
- #undef STRICT_NEXT_BEHAVIOUR
-
-
- typedef struct W_Slider {
- W_Class widgetClass;
- WMView *view;
-
- int minValue;
- int maxValue;
-
- int value;
-
- Pixmap knobPixmap;
- WMPixmap *backPixmap;
-
- WMAction *action;
- void *clientData;
-
- int knobThickness;
-
- struct {
- unsigned int continuous:1;
-
- unsigned int vertical:1;
- unsigned int dragging:1;
- } flags;
-
- } Slider;
-
-
-
-
- static void didResizeSlider();
-
-
- W_ViewDelegate _SliderViewDelegate = {
- NULL,
- NULL,
- didResizeSlider,
- NULL,
- NULL
- };
-
-
-
- static void destroySlider(Slider *sPtr);
- static void paintSlider(Slider *sPtr);
- static void realizeSlider(Slider *sPtr);
-
- static void handleEvents(XEvent *event, void *data);
- static void handleActionEvents(XEvent *event, void *data);
-
- static void makeKnobPixmap(Slider *sPtr);
-
- static void
- realizeObserver(void *self, WMNotification *not)
- {
- realizeSlider(self);
- }
-
-
-
- WMSlider*
- WMCreateSlider(WMWidget *parent)
- {
- Slider *sPtr;
-
- sPtr = wmalloc(sizeof(Slider));
- memset(sPtr, 0, sizeof(Slider));
-
- sPtr->widgetClass = WC_Slider;
-
- sPtr->view = W_CreateView(W_VIEW(parent));
- if (!sPtr->view) {
- wfree(sPtr);
- return NULL;
- }
- sPtr->view->self = sPtr;
-
- sPtr->view->delegate = &_SliderViewDelegate;
-
- WMCreateEventHandler(sPtr->view, ExposureMask|StructureNotifyMask,
- handleEvents, sPtr);
-
-
- WMCreateEventHandler(sPtr->view, ButtonPressMask|ButtonReleaseMask
- |EnterWindowMask|LeaveWindowMask|ButtonMotionMask,
- handleActionEvents, sPtr);
-
- W_ResizeView(sPtr->view, 100, 16);
- sPtr->flags.vertical = 0;
- sPtr->minValue = 0;
- sPtr->maxValue = 100;
- sPtr->value = 50;
-
- sPtr->knobThickness = 20;
-
- sPtr->flags.continuous = 1;
-
- WMAddNotificationObserver(realizeObserver, sPtr,
- WMViewRealizedNotification, sPtr->view);
-
- return sPtr;
- }
-
-
- void
- WMSetSliderImage(WMSlider *sPtr, WMPixmap *pixmap)
- {
- if (sPtr->backPixmap)
- WMReleasePixmap(sPtr->backPixmap);
-
- sPtr->backPixmap = WMRetainPixmap(pixmap);
-
- if (sPtr->view->flags.mapped) {
- paintSlider(sPtr);
- }
- }
-
-
- void
- WMSetSliderKnobThickness(WMSlider *sPtr, int thickness)
- {
- assert(thickness > 0);
-
- sPtr->knobThickness = thickness;
-
- if (sPtr->knobPixmap) {
- makeKnobPixmap(sPtr);
- }
-
- if (sPtr->view->flags.mapped) {
- paintSlider(sPtr);
- }
- }
-
-
- int
- WMGetSliderMinValue(WMSlider *slider)
- {
- CHECK_CLASS(slider, WC_Slider);
-
- return slider->minValue;
- }
-
-
- int
- WMGetSliderMaxValue(WMSlider *slider)
- {
- CHECK_CLASS(slider, WC_Slider);
-
- return slider->maxValue;
- }
-
-
- int
- WMGetSliderValue(WMSlider *slider)
- {
- CHECK_CLASS(slider, WC_Slider);
-
- return slider->value;
- }
-
-
- void
- WMSetSliderMinValue(WMSlider *slider, int value)
- {
- CHECK_CLASS(slider, WC_Slider);
-
- slider->minValue = value;
- if (slider->value < value) {
- slider->value = value;
- if (slider->view->flags.mapped)
- paintSlider(slider);
- }
- }
-
-
- void
- WMSetSliderMaxValue(WMSlider *slider, int value)
- {
- CHECK_CLASS(slider, WC_Slider);
-
- slider->maxValue = value;
- if (slider->value > value) {
- slider->value = value;
- if (slider->view->flags.mapped)
- paintSlider(slider);
- }
- }
-
-
- void
- WMSetSliderValue(WMSlider *slider, int value)
- {
- CHECK_CLASS(slider, WC_Slider);
-
- if (value < slider->minValue)
- slider->value = slider->minValue;
- else if (value > slider->maxValue)
- slider->value = slider->maxValue;
- else
- slider->value = value;
-
- if (slider->view->flags.mapped)
- paintSlider(slider);
- }
-
-
- void
- WMSetSliderContinuous(WMSlider *slider, Bool flag)
- {
- CHECK_CLASS(slider, WC_Slider);
-
- slider->flags.continuous = flag;
- }
-
-
- void
- WMSetSliderAction(WMSlider *slider, WMAction *action, void *data)
- {
- CHECK_CLASS(slider, WC_Slider);
-
- slider->action = action;
- slider->clientData = data;
- }
-
-
- static void
- makeKnobPixmap(Slider *sPtr)
- {
- Pixmap pix;
- WMScreen *scr = sPtr->view->screen;
- int w, h;
-
- if (sPtr->flags.vertical) {
- w = sPtr->view->size.width-2;
- h = sPtr->knobThickness;
- } else {
- w = sPtr->knobThickness;
- h = sPtr->view->size.height-2;
- }
-
- pix = XCreatePixmap(scr->display, sPtr->view->window, w, h, scr->depth);
- XFillRectangle(scr->display, pix, WMColorGC(scr->gray), 0, 0, w, h);
-
- if (sPtr->knobThickness < 10) {
- W_DrawRelief(scr, pix, 0, 0, w, h, WRRaised);
- } else if (sPtr->flags.vertical) {
- XDrawLine(scr->display, pix, WMColorGC(scr->white), 0, 0, 0, h-3);
- XDrawLine(scr->display, pix, WMColorGC(scr->white), 1, 0, 1, h-3);
- XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w-2, 1, w-2, h/2-2);
- XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w-2, h/2, w-2, h-2);
-
- XDrawLine(scr->display, pix, WMColorGC(scr->white), 0, 0, w-2, 0);
- XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), 1, h/2-2, w-3, h/2-2);
- XDrawLine(scr->display, pix, WMColorGC(scr->white), 0, h/2-1, w-3, h/2-1);
-
- XDrawLine(scr->display, pix, WMColorGC(scr->black), w-1, 0, w-1, h-2);
-
- XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), 0, h-3, w-2, h-3);
- XDrawLine(scr->display, pix, WMColorGC(scr->black), 0, h-2, w-1, h-2);
- XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), 0, h-1, w-1,h-1);
- } else {
- XDrawLine(scr->display, pix, WMColorGC(scr->white), 0, 0, w-3, 0);
-
- XDrawLine(scr->display, pix, WMColorGC(scr->white), 0, 0, 0, h-2);
-
- XDrawLine(scr->display, pix, WMColorGC(scr->white), 1, 0, 1, h-3);
- XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w/2-2, 1, w/2-2, h-3);
- XDrawLine(scr->display, pix, WMColorGC(scr->white), w/2-1, 0, w/2-1, h-3);
-
- XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w-3, 0, w-3, h-2);
- XDrawLine(scr->display, pix, WMColorGC(scr->black), w-2, 0, w-2, h-2);
- XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w-1, 0, w-1, h-1);
-
- XDrawLine(scr->display, pix, WMColorGC(scr->black), 1, h-1, w/2+1, h-1);
- XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), 1, h-2, w/2-2, h-2);
- XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w/2, h-2, w-3,h-2);
-
- XDrawLine(scr->display, pix, WMColorGC(scr->black), 0, h-1, w-2, h-1);
- }
-
- if (sPtr->knobPixmap)
- XFreePixmap(scr->display, sPtr->knobPixmap);
- sPtr->knobPixmap = pix;
- }
-
-
- static void
- realizeSlider(Slider *sPtr)
- {
- W_RealizeView(sPtr->view);
-
- makeKnobPixmap(sPtr);
- }
-
-
- static void
- didResizeSlider(W_ViewDelegate *self, WMView *view)
- {
- Slider *sPtr = (Slider*)view->self;
- int width = sPtr->view->size.width;
- int height = sPtr->view->size.height;
-
- assert(width > 0);
- assert(height > 0);
-
- if (width > height) {
- if (sPtr->flags.vertical) {
- sPtr->flags.vertical = 0;
- if (sPtr->view->flags.realized)
- makeKnobPixmap(sPtr);
- }
- } else {
- if (!sPtr->flags.vertical) {
- sPtr->flags.vertical = 1;
- if (sPtr->view->flags.realized)
- makeKnobPixmap(sPtr);
- }
- }
- }
-
-
-
- static void
- paintSlider(Slider *sPtr)
- {
- W_Screen *scr = sPtr->view->screen;
- GC bgc;
- GC wgc;
- GC lgc;
- WMSize size = sPtr->view->size;
- int pos;
- Pixmap buffer;
-
- #define MINV sPtr->minValue
- #define MAXV sPtr->maxValue
- #define POSV sPtr->value
-
- bgc = WMColorGC(scr->black);
- wgc = WMColorGC(scr->white);
- lgc = WMColorGC(scr->gray);
-
- buffer = XCreatePixmap(scr->display, sPtr->view->window,
- size.width, size.height, scr->depth);
-
- if (sPtr->backPixmap) {
- WMSize size = WMGetPixmapSize(sPtr->backPixmap);
-
- XCopyArea(scr->display, WMGetPixmapXID(sPtr->backPixmap),
- buffer, scr->copyGC, 0, 0, size.width, size.height, 1, 1);
- } else {
- XFillRectangle(scr->display, buffer, lgc, 0, 0, size.width,
- size.height);
- XFillRectangle(scr->display, buffer, scr->stippleGC, 0, 0, size.width,
- size.height);
- }
-
- if (sPtr->flags.vertical) {
- pos = (size.height-2-sPtr->knobThickness)*(POSV-MINV)/(MAXV-MINV)+1;
- /* draw knob */
- XCopyArea(scr->display, sPtr->knobPixmap, buffer,
- scr->copyGC, 0, 0, size.width-2, sPtr->knobThickness,
- 1, pos);
- } else {
- pos = (size.width-2-sPtr->knobThickness)*(POSV-MINV)/(MAXV-MINV)+1;
- /* draw knob */
- XCopyArea(scr->display, sPtr->knobPixmap, buffer,
- scr->copyGC, 0, 0, sPtr->knobThickness, size.height, pos, 1);
- }
-
- XDrawLine(scr->display, buffer, bgc, 0, 0, 0, size.height-1);
- XDrawLine(scr->display, buffer, bgc, 0, 0, size.width, 0);
-
- XDrawLine(scr->display, buffer, wgc, size.width-1, 0,
- size.width-1, size.height-1);
- XDrawLine(scr->display, buffer, wgc, 0, size.height-1,
- size.width-1, size.height-1);
-
- XCopyArea(scr->display, buffer, sPtr->view->window, scr->copyGC, 0, 0,
- size.width, size.height, 0, 0);
- XFreePixmap(scr->display, buffer);
- }
-
-
-
- static void
- handleEvents(XEvent *event, void *data)
- {
- Slider *sPtr = (Slider*)data;
-
- CHECK_CLASS(data, WC_Slider);
-
-
- switch (event->type) {
- case Expose:
- if (event->xexpose.count!=0)
- break;
- paintSlider(sPtr);
- break;
-
- case DestroyNotify:
- destroySlider(sPtr);
- break;
-
- }
- }
-
-
- #define DECR_PART 1
- #define KNOB_PART 2
- #define INCR_PART 3
-
- static int
- getSliderPart(Slider *sPtr, int x, int y)
- {
- int p;
- int pos;
- WMSize size = sPtr->view->size;
-
-
- if (sPtr->flags.vertical) {
- p = y;
- pos = (size.height-2-sPtr->knobThickness)*(POSV-MINV)/(MAXV-MINV);
- if (p < pos)
- return INCR_PART;
- if (p > pos + sPtr->knobThickness)
- return DECR_PART;
- return KNOB_PART;
- } else {
- p = x;
- pos = (size.width-2-sPtr->knobThickness)*(POSV-MINV)/(MAXV-MINV);
- if (p < pos)
- return DECR_PART;
- if (p > pos + sPtr->knobThickness)
- return INCR_PART;
- return KNOB_PART;
- }
- }
-
-
- static int
- valueForMousePoint(Slider *sPtr, int x, int y)
- {
- WMSize size = sPtr->view->size;
- int f;
-
- if (sPtr->flags.vertical) {
- f = (y-sPtr->knobThickness/2)*(MAXV-MINV)
- / ((int)size.height-2-sPtr->knobThickness);
- } else {
- f = (x-sPtr->knobThickness/2)*(MAXV-MINV)
- / ((int)size.width-2-sPtr->knobThickness);
- }
-
- f += sPtr->minValue;
- if (f < sPtr->minValue)
- f = sPtr->minValue;
- else if (f > sPtr->maxValue)
- f = sPtr->maxValue;
-
- return f;
- }
-
-
- static void
- handleActionEvents(XEvent *event, void *data)
- {
- WMSlider *sPtr = (Slider*)data;
-
- CHECK_CLASS(data, WC_Slider);
-
-
- switch (event->type) {
- case ButtonPress:
- if (getSliderPart(sPtr, event->xbutton.x, event->xbutton.y)==KNOB_PART)
- sPtr->flags.dragging = 1;
- else {
- #ifdef STRICT_NEXT_BEHAVIOUR
- sPtr->flags.dragging = 1;
-
- sPtr->value = valueForMousePoint(sPtr, event->xmotion.x,
- event->xmotion.y);
- paintSlider(sPtr);
- #else
- int tmp;
-
- if (event->xbutton.button == Button2) {
- sPtr->flags.dragging = 1;
-
- sPtr->value = valueForMousePoint(sPtr, event->xmotion.x,
- event->xmotion.y);
- paintSlider(sPtr);
- } else {
- tmp = valueForMousePoint(sPtr, event->xmotion.x,
- event->xmotion.y);
- if (tmp < sPtr->value)
- tmp = sPtr->value-1;
- else
- tmp = sPtr->value+1;
- WMSetSliderValue(sPtr, tmp);
- }
- #endif
-
- if (sPtr->flags.continuous && sPtr->action) {
- (*sPtr->action)(sPtr, sPtr->clientData);
- }
- }
- break;
-
- case ButtonRelease:
- if (!sPtr->flags.continuous && sPtr->action) {
- (*sPtr->action)(sPtr, sPtr->clientData);
- }
- sPtr->flags.dragging = 0;
- break;
-
- case MotionNotify:
- if (sPtr->flags.dragging) {
- sPtr->value = valueForMousePoint(sPtr, event->xmotion.x,
- event->xmotion.y);
- paintSlider(sPtr);
-
- if (sPtr->flags.continuous && sPtr->action) {
- (*sPtr->action)(sPtr, sPtr->clientData);
- }
- }
- break;
- }
- }
-
-
-
- static void
- destroySlider(Slider *sPtr)
- {
- if (sPtr->knobPixmap)
- XFreePixmap(sPtr->view->screen->display, sPtr->knobPixmap);
-
- if (sPtr->backPixmap)
- WMReleasePixmap(sPtr->backPixmap);
-
- WMRemoveNotificationObserver(sPtr);
-
- wfree(sPtr);
- }
-
-